package models

import (
	"fmt"
	"math"
)

//定义一个发送数据的字符串数组
type Buff struct {
	Buff []byte //对外空间，是个可变的，指向buff的指针
	//buff []byte //实际上不会变动的空间
}

//申请一个空间
func CreateBuff(maxlen int) *Buff {
	ret := &Buff{}
	ret.Buff = make([]byte, 0, maxlen)
	return ret
}
func (z *Buff) AddBool(bl bool) {
	if bl == true {
		z.AddBytes([]byte{01})
	} else {
		z.AddBytes([]byte{00})
	}
}

//功能 从缓冲区中读取一个布尔值
func (z *Buff) GetBool() bool {
	if z.GetByte() == 0 {
		return false
	} else {
		return true
	}
}

//功能 添加字符串
func (z *Buff) AddByte(by byte) {
	z.AddBytes([]byte{by})
}
func (z *Buff) GetByte() byte {
	ret := z.Buff[0]
	z.Buff = z.Buff[1:]
	return ret
}
func (z *Buff) AddInt16(d int16) {
	for i := 0; i < 2; i++ {
		z.Buff = append(z.Buff, byte(d))
		d >>= 8
	}
}
func (z *Buff) GetInt16() int16 {
	var ret int16
	for i := 0; i < 2; i++ {
		ret <<= 8
		ret |= int16(z.Buff[1-i])
	}
	z.Buff = z.Buff[2:]
	return ret
}
func (z *Buff) AddInt32(d int32) {
	for i := 0; i < 4; i++ {
		z.Buff = append(z.Buff, byte(d))
		d >>= 8
	}
}
func Float2Int(f float32) int {
	return int(math.Float32bits(f))
}
func Int2Float(i int) float32 {
	return math.Float32frombits(uint32(i))
}
func (z *Buff) AddFloat(d float32) {
	bits := math.Float32bits(d)
	for i := 0; i < 4; i++ {
		z.Buff = append(z.Buff, byte(bits))
		bits >>= 8
	}
}
func (z *Buff) GetFloat() float32 {
	t := z.GetInt32()
	return math.Float32frombits(uint32(t))
}
func (z *Buff) GetUInt32() uint32 {
	var ret uint32
	for i := 0; i < 4; i++ {
		ret <<= 8
		ret |= uint32(z.Buff[3-i])
	}
	z.Buff = z.Buff[4:]
	return uint32(ret)
}
func (z *Buff) GetInt32() int32 {
	var ret int32
	for i := 0; i < 4; i++ {
		ret <<= 8
		ret |= int32(z.Buff[3-i])
	}
	z.Buff = z.Buff[4:]
	return ret
}
func (z *Buff) AddInt64(d int64) {
	for i := 0; i < 8; i++ {
		z.Buff = append(z.Buff, byte(d))
		d >>= 8
	}
}
func (z *Buff) GetInt64() int64 {
	var ret int64
	for i := 0; i < 8; i++ {
		ret <<= 8
		ret |= int64(z.Buff[7-i])
	}
	z.Buff = z.Buff[8:]
	return ret
}

//功能 添加字符串
func (z *Buff) AddString(s string) {
	z.AddBytes([]byte(UTF8ToGBK(s)))
}
func (z *Buff) GetString() string {
	ret := ""
	for i, v := range z.Buff {
		if v == 0 {
			ret = string(z.Buff[:i])
			z.Buff = z.Buff[i+1:]
		}
	}
	return ret
}

//功能 添加一个字符串，外加上字符串的长度
func (z *Buff) AddStringAndLen(s string) {
	bys := []byte(UTF8ToGBK(s))
	if (len(bys) != 0) && (bys[len(bys)-1] == 0) {
		z.AddInt32(int32(len(bys)))
		z.AddBytes(bys)
	} else {
		z.AddInt32(int32(len(bys) + 1)) //最后还有一个结束符
		z.AddBytes(bys)
		z.AddByte(0) //
	}
}
func (z *Buff) GetStringAndLen() string {
	n := z.GetInt32()
	ret := ""
	if n > 0 {
		ret = GBKToUTF8(string(z.Buff[:n-1]))
	}
	z.Buff = z.Buff[n:]
	return ret
}

//功能 添加字符数组
func (z *Buff) AddBytes(d []byte) {
	for _, v := range d {
		z.Buff = append(z.Buff, v)
	}
}
func (z *Buff) GetBytes(lenght int) []byte {
	var ret []byte
	ret = z.Buff[:lenght]
	z.Buff = z.Buff[lenght:]
	return ret
}
func Byte2String(bys []byte) string {
	ret := ""
	for _, v := range bys {
		ret += fmt.Sprintf("%02X ", v)
	}
	return ret
}

//将一个字符串转为HEX数组
func String2Byte(s string) []byte {
	var ret []byte
	isfull := true //是否全了
	var by byte
	for _, v := range s {
		if v == ' ' {
			continue
		} else if v >= '0' && v <= '9' {
			by <<= 4
			by += byte(v - '0')
		} else if v >= 'a' && v <= 'z' {
			by <<= 4
			by += byte(v-'a') + 10
		} else if v >= 'A' && v <= 'Z' {
			by <<= 4
			by += byte(v-'A') + 10
		} else {
			panic("转换字符出错:" + string(v))
		}
		if isfull == false {
			ret = append(ret, by)
			isfull = true
		} else {
			isfull = false
		}
	}
	return ret
}
